import { shopmanager } from "proto-ts/shopmanager/shop";
import { shopmanager as accountmanager } from "proto-ts/shopmanager/account";
import { third_auth } from "proto-ts/third-auth/account";
import { credentials } from "@grpc/grpc-js";
import { Service } from "typedi";
import { GRPC_ADDRESS, GRPC_ADDRESS_3 } from "config/config";
import { setReqHeader, REPO_ERR, RES_INFO } from "config/const";
import { HttpParams } from "client/configVo";

const conn = new shopmanager.ShopServiceClient(
  GRPC_ADDRESS,
  credentials.createInsecure()
);

const conn_3 = new third_auth.AccountServiceClient(
  GRPC_ADDRESS_3,
  credentials.createInsecure()
);

const conn_4 = new accountmanager.AccountServiceClient(
  GRPC_ADDRESS,
  credentials.createInsecure()
);

const textEncoder = new TextEncoder();
export const REPO_SITE_INTERFACE = "repoSiteInterface";

export interface sitesEntity {
  ID: number; // 唯一ID
  CreatedAt?: string; // 创建时间
  UpdatedAt?: string; // 更新时间
  DeletedAt?: string; // 删除时间
  OrganizationID?: number; // 关联组织ID
  AccountID?: number; // 关联账户ID
}

export interface accountEntity {
  Type?: string;
  UID?: string;
}

export interface repoSiteInterface {
  getSites(opts: HttpParams): Promise<sitesEntity | any>; // 从独立站获取店铺列表
  get_create_info(opts: HttpParams): Promise<sitesEntity | any>;
  create(opts: HttpParams): Promise<sitesEntity | any>;
  update(opts: HttpParams): Promise<sitesEntity | any>;
  delete(opts: HttpParams): Promise<sitesEntity | any>;
  getHost(opts: HttpParams): Promise<sitesEntity | any>;
  updateVerify(opts: HttpParams): Promise<sitesEntity | any>;
  updateOrign(opts: HttpParams): Promise<sitesEntity | any>;
  updateStatus(opts: HttpParams): Promise<sitesEntity | any>;
  getZjzOptions(opts: HttpParams): Promise<sitesEntity | any>;
}

@Service(REPO_SITE_INTERFACE)
class repo implements repoSiteInterface {
  // 获取店铺列表
  async getSites(opts: HttpParams): Promise<sitesEntity | any> {
    const { request, response, userInfo, query } = opts;
    const header = setReqHeader(userInfo);
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.List(
        new shopmanager.ListShopParam(query || request.body),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "获取店铺列表"));
          const setting = <any>resp?.toObject();
          resolve(
            RES_INFO({
              data: {
                list: setting?.list,
                total: setting?.total || 0,
              },
            })
          );
        }
      );
    });
  }

  // 获取创建时的账号信息
  get_create_info(opts: HttpParams): Promise<sitesEntity | any> {
    let { request, response, userInfo, query } = opts;
    const header = setReqHeader(userInfo);
    query = query || request.body;
    query.conditions = query.conditions?.map((item: any) => {
      return new third_auth.Conditions({
        key: item.key,
        operation: item.operation,
        values: item.values.map((it: any) => {
          return new third_auth.Any({ String: String(it) });
        }),
      });
    });

    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn_3.ListAccount(
        new third_auth.AccountListRequest({
          param: new third_auth.AccountListParam(query),
        }),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "获取创建时的账号信息"));
          const setting = <any>resp?.toObject();
          resolve(
            RES_INFO({
              data: {
                list: setting?.list || [],
                total: setting?.total || 0,
              },
            })
          );
        }
      );
    });
  }

  // 创建店铺
  create(opts: HttpParams): Promise<sitesEntity | any> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body || {};
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.Create(
        new shopmanager.CreateShopParam({
          ...query,
          customize: query.customize
            ? textEncoder.encode(JSON.stringify(query.customize))
            : undefined,
          proxy: query.proxy
            ? new shopmanager.ProxyParam(query.proxy)
            : undefined,
        }),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "创建店铺"));
          resolve(RES_INFO({}));
        }
      );
    });
  }

  // 更新店铺
  update(opts: HttpParams): Promise<sitesEntity | any> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body;
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.Update(
        new shopmanager.UpdateShopParam({
          ...query,
          id: Number(query.id),
          customize: query.customize
            ? textEncoder.encode(JSON.stringify(query.customize))
            : undefined,
          proxy: query.proxy
            ? new shopmanager.ProxyParam(query.proxy)
            : undefined,
        }),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "更新店铺"));
          resolve(RES_INFO({}));
        }
      );
    });
  }

  // 删除店铺
  delete(opts: HttpParams): Promise<sitesEntity | any> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body;
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.Delete(
        new shopmanager.DeleteShopParam(query),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "删除店铺"));
          resolve(RES_INFO({}));
        }
      );
    });
  }

  // 获取店铺后台域名列表
  getHost(opts: HttpParams): Promise<sitesEntity | any> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.query;
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn_4.List(
        new accountmanager.ListAccountParam(query),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "获取店铺后台域名列表"));
          const setting = <any>resp?.toObject();
          resolve(
            RES_INFO({
              data: {
                list: setting?.list || [],
                total: setting?.total || 0,
              },
            })
          );
        }
      );
    });
  }

  // 批量更新专利校验设置
  async updateVerify(opts: HttpParams): Promise<sitesEntity[]> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body;
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.BatchUpdatePatentVerify(
        new shopmanager.BatchUpdatePatentVerifyParam(query),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "批量更新专利校验设置"));
          resolve(RES_INFO({}));
        }
      );
    });
  }

  // 批量变更店铺店铺归属
  async updateOrign(opts: HttpParams): Promise<sitesEntity[]> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body;
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.BatchUpdateOrignization(
        new shopmanager.BatchUpdateOrignizationParam(query),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "批量变更店铺店铺归属"));
          resolve(RES_INFO({}));
        }
      );
    });
  }

  // 批量设置店铺状态
  async updateStatus(opts: HttpParams): Promise<sitesEntity[]> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body;
    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn.BatchUpdateStatus(
        new shopmanager.BatchUpdateStatusParam(query),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "批量设置店铺状态"));
          resolve(RES_INFO({}));
        }
      );
    });
  }

  // 获取自建站域名下拉
  async getZjzOptions(opts: HttpParams): Promise<sitesEntity[]> {
    const { request, response, userInfo } = opts;
    const header = setReqHeader(userInfo);
    const query = request.body;
    query.conditions = query.conditions?.map((item: any) => {
      return new third_auth.Conditions({
        key: item.key,
        operation: item.operation,
        values: item.values.map((it: any) => {
          return new third_auth.Any({ String: String(it) });
        }),
      });
    });

    return new Promise<sitesEntity | any>((resolve, reject) => {
      conn_3.ListAccount(
        new third_auth.AccountListRequest({
          param: new third_auth.AccountListParam(query),
        }),
        header,
        (err, resp) => {
          if (err) return resolve(REPO_ERR(err, "获取自建站域名下拉"));
          const setting = <any>resp?.toObject();

          resolve(
            RES_INFO({
              data: {
                list: setting?.list || [],
                total: setting?.total || 0,
              },
            })
          );
        }
      );
    });
  }
}
